package com.YKFuse.bean.beanprocessor;

import com.YKFuse.annotion.YKFuse;
import com.YKFuse.bean.operation.pool.YKFusePoolOperation;
import com.YKFuse.wrapper.calculate.BeanMethodCalculateProxyFactory;
import lombok.Data;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

import java.lang.reflect.Method;
import java.util.HashSet;

/**
 * @author yuank
 * @version 1.0.0
 * @date 2025/2/10 15:55:49
 *
 * 用于 快速配置
 */
@Data
public class YKFusePostProcessor implements BeanPostProcessor {

    /**
     * 熔断池
     */
    private YKFusePoolOperation ykFusePoolOperation;
    /**
     * 需要熔断支持的bean的方法
     */
    private HashSet<Method> methodSet;// 如果说考虑高并发可以采取 ConcurrentHashMap 也可以不需要对计数的字段进行volatile化即可

    public YKFusePostProcessor(YKFusePoolOperation ykFusePoolOperation) {
        this.ykFusePoolOperation = ykFusePoolOperation;
        this.methodSet = new HashSet<>();
    }


    @Override
    //每个bean都会陆续传参此
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //当前bean及其所有的方法
        Class<?> beanClass = bean.getClass();
        Method[] allMethod = beanClass.getDeclaredMethods();

        //每个方法校验是否需要熔断支持
        for (Method method : allMethod) {
            if (method.isAnnotationPresent(YKFuse.class)){
                methodSet.add(method);
            }
        }

        //当前bean进行代理的生成
        if (!methodSet.isEmpty()) {
            try {
                return BeanMethodCalculateProxyFactory.createProxy(bean, methodSet, ykFusePoolOperation);
            } catch (NoSuchFieldException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }

        return bean;
    }
}